package com.itany.book.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.itany.constant.Constant;
import com.itany.exception.BookDisabledException;
import com.itany.exception.FileUploadErrorException;
import com.itany.exception.RequestParamsException;
import com.itany.mapper.*;
import com.itany.pojo.*;
import com.itany.service.BookService;
import com.itany.utils.MyHttpClientUtils;
import com.itany.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ResourceUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * @author mofeibai
 */
@Service
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
public class BookServiceImpl implements BookService {

    @Autowired
    BookMapper bookMapper;

    @Autowired
    ExamineMapper examineMapper;

    @Autowired
    BookSupplierMapper bookSupplierMapper;

    @Autowired
    PressMapper pressMapper;

    @Override
    public Book getBooksinfoOnline(String ISBN) throws RequestParamsException {
        if (StrUtil.isBlankIfStr(ISBN)) {
            throw new RequestParamsException("请求参数缺失");
        }
        Book book = bookMapper.selectByIsbn(ISBN);
        if (book == null) {
            String result = MyHttpClientUtils.doGet(Constant.BASE_ISBN_API_URL + ISBN);
            JSONObject jsonObject = JSON.parseObject(result);
            if (Constant.SUCCESS_ERROR_CODE.equals(jsonObject.getInteger(Constant.ERROR_CODE_KEY))) {
                JSONObject dataJsonObject = jsonObject.getJSONObject(Constant.DATA_KEY);
                book = new Book();
                book.setISBN(dataJsonObject.getString("isbn13"));
                book.setBookname(dataJsonObject.getString("title"));
                book.setAuthor(dataJsonObject.getString("author"));
                book.setPrice(dataJsonObject.getDouble("price"));
                book.setGroupprice(dataJsonObject.getDouble("price"));
                book.setBookintroduce(dataJsonObject.getString("summary"));
                String pubdate = dataJsonObject.getString("pubdate").replaceAll("-(\\d)(?!\\d)", "-0$1");
                System.out.println(pubdate);
                try {
                    book.setPublishdate(new SimpleDateFormat("yyyy-MM-dd").parse(pubdate));
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                book.setImgurl(dataJsonObject.getString("images_medium"));
                //添加到出版社
                String publisher = dataJsonObject.getString("publisher");
                Press press = pressMapper.selectByName(publisher);
                if (press == null) {
                    press = new Press();
                    press.setName(publisher);
                    press.setFlag(Constant.ENABLE_STATUS);
                    pressMapper.insertPress(press);
                }
                book.setPress(press);
                book.setPagenumber(dataJsonObject.getString("pages"));
                bookMapper.addBook(book);
            }
        }
        return book;
    }


    /**
     * 供应商添加图入库业务
     *
     * @param bookname        书名
     * @param ISBN            ISBN号
     * @param price           单价
     * @param number          数量
     * @param groupprice      团购价
     * @param bookintroduce   图书信息
     * @param authorintroduce 作者信息
     * @param file            封面图片文件
     */
    @Override
    public void addBook(String bookname, String ISBN, String price, String number, String groupprice, String pagenumber,
                        String author, String publishdate, String bookintroduce, String authorintroduce,
                        MultipartFile file, HttpSession session) throws RequestParamsException, BookDisabledException,
            FileUploadErrorException {
        if (StrUtil.isEmptyIfStr(bookname) || StrUtil.isEmptyIfStr(ISBN) || StrUtil.isEmptyIfStr(price) || StrUtil.isEmptyIfStr(number) || StrUtil.isEmptyIfStr(groupprice) || StrUtil.isEmptyIfStr(pagenumber) || StrUtil.isEmptyIfStr(author) || StrUtil.isEmptyIfStr(publishdate) || StrUtil.isEmptyIfStr(bookintroduce) || StrUtil.isEmptyIfStr(authorintroduce) || session == null) {
            throw new RequestParamsException("请求参数缺失");
        }
        //判断是否存在图书信息，采取不同的处理逻辑
        Book aBook = bookMapper.selectByIsbn(ISBN);
        Integer bookId = aBook.getId();

        //图书信息存在，且可以上架(状态为1)，直接添加信息到审核表中,否则抛出异常
        if (Constant.DISABLE_STATUS.equals(aBook.getFlag())) {
            throw new BookDisabledException("该图书禁止上架");
        } else {
            //返回添加图书的主键
            aBook = new Book();
            try {
                aBook.setNumber(Constant.INIT_BOOK_NUMBER);
                aBook.setPrice(Double.parseDouble(price));
                aBook.setGroupprice(Double.parseDouble(groupprice));
            } catch (NumberFormatException e) {
                throw new RequestParamsException("请求参数格式错误");
            }
            aBook.setISBN(ISBN);
            try {
                aBook.setPublishdate(new SimpleDateFormat("yyyy-MM-dd").parse(publishdate));
            } catch (ParseException e) {
                throw new RequestParamsException("出版日期格式错误");
            }
            aBook.setAuthorintroduce(authorintroduce);
            aBook.setCreatetime(new Date());
            aBook.setFlag(Constant.UNDER_REVIEW);

            //图片上传业务
            if (file != null && !file.isEmpty()) {
                String path =
                        Constant.BOOK_IMAGE_ROOT_DIRECTORY + new SimpleDateFormat("yyyyMMdd").format(new Date());
                try {
                    String cp = ResourceUtils.getURL("classpath:static").getPath() + path;
                    File imgFile = new File(cp);
                    imgFile.mkdirs();
                    System.out.println("图片上传路径:" + cp);
                    String fileName = file.getOriginalFilename();
                    fileName = StringUtils.rename(fileName);
                    aBook.setImgurl(path + "/" + fileName);
                    // 添加
                    bookMapper.updateOnlineBook(aBook);
                    // 上传
                    file.transferTo(new File(cp, fileName));
                } catch (IOException e) {
                    throw new FileUploadErrorException("文件上传失败");
                }
            } else {
                bookMapper.updateOnlineBook(aBook);
            }

            Examine examine = new Examine();
            Book ecamineBook = new Book();
            ecamineBook.setId(bookId);
            examine.setBook(ecamineBook);
            examine.setNumber(Integer.parseInt(number));
            ManagerUser managerUser = (ManagerUser) session.getAttribute("login");
            examine.setSupplier(managerUser.getSupplier());
            examine.setTitle("《" + bookname + "》正在审核");
            examine.setFlag(Constant.UNDER_REVIEW);
            examineMapper.insertExamine(examine);
        }
    }

    @Override
    public void modifyBook(String bookid, String bookname, String price, String groupprice,
                           String bookintroduce, String authorintroduce,
                           MultipartFile file) throws RequestParamsException, FileUploadErrorException {
        if (StrUtil.isEmptyIfStr(bookid)) {
            throw new RequestParamsException("请求参数缺失");
        }
        Integer id;
        Double aPrice;
        Double aGroupprice;
        try {
            id = Integer.parseInt(bookid);
            aPrice = Double.parseDouble(price);
            aGroupprice = Double.parseDouble(groupprice);
        } catch (NumberFormatException e) {
            throw new RequestParamsException("请求参数格式错误");
        }
        Book book = new Book();
        book.setId(id);
        book.setBookname(bookname);
        book.setPrice(aPrice);
        book.setGroupprice(aGroupprice);
        book.setBookintroduce(bookintroduce);
        book.setAuthorintroduce(authorintroduce);


        //图片上传业务
        if (file != null && !file.isEmpty()) {
            String path = Constant.BOOK_IMAGE_ROOT_DIRECTORY + new SimpleDateFormat("yyyyMMdd").format(new Date());
            try {
                String cp = ResourceUtils.getURL("classpath:static").getPath() + path;
                File imgFile = new File(cp);
                imgFile.mkdirs();
                System.out.println("图片上传路径:" + cp);
                String fileName = file.getOriginalFilename();
                fileName = StringUtils.rename(fileName);
                book.setImgurl(path + "/" + fileName);
                // 添加
                bookMapper.updateBook(book);
                // 上传
                file.transferTo(new File(cp, fileName));
            } catch (IOException e) {
                throw new FileUploadErrorException("文件上传失败");
            }
        } else {
            bookMapper.updateBook(book);
        }
    }

    /**
     * 展示所有入库图书
     */
    @Override
    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
    public PageInfo<Book> findAllBooks(Integer page, Integer rows, String booknameKey, String ISBNKey,
                                       String supplierId, String pressId) {
        List<Book> list;
        Integer supplierIdInt = null;
        Integer pressIdInt = null;
        if (!StrUtil.isEmptyIfStr(supplierId)) {
            supplierIdInt = Integer.parseInt(supplierId);
        }
        if (!StrUtil.isEmptyIfStr(pressId)) {
            pressIdInt = Integer.parseInt(pressId);

        }
        PageHelper.startPage(page, rows);
        list = bookMapper.selectAll(StringUtils.escapeStr(booknameKey), StringUtils.escapeStr(ISBNKey), supplierIdInt
                , pressIdInt);
        for (Book book : list) {
            List<Supplier> suppliers = bookSupplierMapper.selectSuppliersByBook(book.getId());
            book.setSuppliers(suppliers);
        }

        return new PageInfo<>(list);
    }


    /**
     * 展示指定供货商的入库图书
     */
    @Override
    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
    public PageInfo<BookSupplier> findBooksBySupplier(Integer page, Integer rows, HttpSession session,
                                                      String booknameKey, String ISBNKey) {
        PageHelper.startPage(page, rows);
        List<BookSupplier> list;
        ManagerUser managerUser = (ManagerUser) session.getAttribute("login");
        list = bookSupplierMapper.selectBooksBySupplier(managerUser.getSupplier().getId(),
                StringUtils.escapeStr(booknameKey),
                StringUtils.escapeStr(ISBNKey));
        for (BookSupplier bookSupplier : list) {
            Integer sellnum = bookSupplier.getSellnum();
            BigDecimal price = bookSupplier.getBook().getPrice();
            bookSupplier.setTotalMoney(price.multiply(new BigDecimal(sellnum)).setScale(2, BigDecimal.ROUND_HALF_UP));
        }
        return new PageInfo<>(list);
    }


    /**
     * 修改指定用户状态
     *
     * @param id     图书id
     * @param status 更新后的状态
     */
    @Override
    public void modifyStatus(String id, Integer status) throws RequestParamsException {
        if (StrUtil.isEmptyIfStr(id) || status == null) {
            throw new RequestParamsException("请求参数缺失");
        }
        if (!Constant.ENABLE_STATUS.equals(status) && !Constant.DISABLE_STATUS.equals(status)) {
            throw new RequestParamsException("请求参数格式有误");
        }
        Integer idInt;
        try {
            idInt = Integer.parseInt(id);
        } catch (NumberFormatException e) {
            throw new RequestParamsException("请求参数格式错误");
        }
        List<BookSupplier> bookSuppliers = bookSupplierMapper.selectByBook(idInt);
        if (bookSuppliers.isEmpty() && Constant.ENABLE_STATUS.equals(status)) {
            status = Constant.BOOK_OUT_OF_STOCK;
        } else if (Constant.ENABLE_STATUS.equals(status)) {
            boolean flag = true;
            for (BookSupplier bookSupplier : bookSuppliers) {
                if (bookSupplier.getNumber() - bookSupplier.getSellnum() != 0) {
                    flag = false;
                }
            }
            if (flag) {
                status = Constant.BOOK_OUT_OF_STOCK;
            }
        }
        bookMapper.updateStatus(status, idInt);
    }
}
